{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn import metrics, datasets\n",
    "from sklearn.semi_supervised import LabelPropagation  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 加载数据 这里使用sklearn自带的糖尿病数据\n",
    "def load_data():\n",
    "    '''\n",
    "    加载数据集\n",
    "    返回一个元祖，依次是：样本集合、样本标记集合、未标记样本的下标集合\n",
    "    '''\n",
    "    digits = datasets.load_digits()\n",
    "    ### 混洗样本 ###\n",
    "    rng = np.random.RandomState(0)\n",
    "    indices = np.arange(len(digits.data)) # 样本的下标集合\n",
    "    \n",
    "    rng.shuffle(indices) # 混洗样本下标集合\n",
    "    X = digits.data[indices]\n",
    "    Y = digits.target[indices]\n",
    "    ### 生成未标记样本的下标集合 ###\n",
    "    n_labeled_points = int(len(Y)/10)  # 总样本数除以10 ，即只有十分之一的数据有标记\n",
    "    unlabeled_indices = np.arange(len(Y))[n_labeled_points:] # 其余的样本未标记\n",
    "    \n",
    "    return X, Y, unlabeled_indices"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy:0.948084\n"
     ]
    }
   ],
   "source": [
    "def test_LabelPropagation(*data):\n",
    "    '''\n",
    "    测试 LabelPropagation 的用法\n",
    "\n",
    "    :param data: 一个元组，依次为： 样本集合、样本标记集合、 未标记样本的下标集合\n",
    "    :return: None\n",
    "    '''\n",
    "    X,y,unlabeled_indices=data\n",
    "    y_train=np.copy(y) # 必须拷贝，后面要用到 y\n",
    "    y_train[unlabeled_indices]=-1 # 未标记样本的标记设定为 -1\n",
    "    clf=LabelPropagation(max_iter=100,kernel='rbf',gamma=0.1)\n",
    "    clf.fit(X,y_train)\n",
    "    ### 获取预测准确率\n",
    "    predicted_labels = clf.transduction_[unlabeled_indices] # 预测标记\n",
    "    true_labels = y[unlabeled_indices] # 真实标记\n",
    "    print(\"Accuracy:%f\"%metrics.accuracy_score(true_labels,predicted_labels))\n",
    "    # 或者 print(\"Accuracy:%f\"%clf.score(X[unlabeled_indices],true_labels))\n",
    "\n",
    "\n",
    "X, Y, unlabeled_indices = load_data()\n",
    "test_LabelPropagation(X, Y, unlabeled_indices)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.6/site-packages/sklearn/semi_supervised/label_propagation.py:288: ConvergenceWarning: max_iter=100 was reached without convergence.\n",
      "  category=ConvergenceWarning\n",
      "/usr/local/lib/python3.6/site-packages/sklearn/semi_supervised/label_propagation.py:277: RuntimeWarning: invalid value encountered in true_divide\n",
      "  self.label_distributions_ /= normalizer\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# rbf核 及其参数的影响\n",
    "def test_LabelPropagation_rbf(*data):\n",
    "    '''\n",
    "    测试 LabelPropagation 的 rbf 核时，预测性能随 alpha 和 gamma 的变化\n",
    "\n",
    "    :param data: 一个元组，依次为： 样本集合、样本标记集合、 未标记样本的下标集合\n",
    "    :return: None\n",
    "    '''\n",
    "    X,y,unlabeled_indices=data\n",
    "    y_train=np.copy(y) # 必须拷贝，后面要用到 y\n",
    "    y_train[unlabeled_indices]=-1 # 未标记样本的标记设定为 -1\n",
    "\n",
    "    fig=plt.figure()\n",
    "    ax=fig.add_subplot(1,1,1)\n",
    "    alphas=np.linspace(0.01,1,num=10,endpoint=True)\n",
    "    gammas=np.logspace(-2,2,num=50)\n",
    "    colors=((1,0,0),(0,1,0),(0,0,1),(0.5,0.5,0),(0,0.5,0.5),(0.5,0,0.5),\n",
    "        (0.4,0.6,0),(0.6,0.4,0),(0,0.6,0.4),(0.5,0.3,0.2),) # 颜色集合，不同曲线用不同颜色\n",
    "    ## 训练并绘图\n",
    "    for alpha,color in zip(alphas,colors):\n",
    "        scores=[]\n",
    "        for gamma in gammas:\n",
    "            clf=LabelPropagation(max_iter=100,gamma=gamma,alpha=alpha,kernel='rbf')\n",
    "            clf.fit(X,y_train)\n",
    "            scores.append(clf.score(X[unlabeled_indices],y[unlabeled_indices]))\n",
    "        ax.plot(gammas,scores,label=r\"$\\alpha=%s$\"%alpha,color=color)\n",
    "\n",
    "    ### 设置图形\n",
    "    ax.set_xlabel(r\"$\\gamma$\")\n",
    "    ax.set_ylabel(\"score\")\n",
    "    ax.set_xscale(\"log\")\n",
    "    ax.legend(loc=\"best\")\n",
    "    ax.set_title(\"LabelPropagation rbf kernel\")\n",
    "    plt.show()\n",
    "    \n",
    "\n",
    "X, Y, unlabeled_indices = load_data()\n",
    "test_LabelPropagation_rbf(X, Y, unlabeled_indices)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.6/site-packages/sklearn/semi_supervised/label_propagation.py:277: RuntimeWarning: invalid value encountered in true_divide\n",
      "  self.label_distributions_ /= normalizer\n",
      "/usr/local/lib/python3.6/site-packages/sklearn/semi_supervised/label_propagation.py:288: ConvergenceWarning: max_iter=100 was reached without convergence.\n",
      "  category=ConvergenceWarning\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "def test_LabelPropagation_knn(*data):\n",
    "    '''\n",
    "   测试 LabelPropagation 的 knn 核时，预测性能随 alpha 和 n_neighbors 的变化\n",
    "\n",
    "    :param data:  一个元组，依次为： 样本集合、样本标记集合、 未标记样本的下标集合\n",
    "    :return:  None\n",
    "    '''\n",
    "    X,y,unlabeled_indices=data\n",
    "    y_train=np.copy(y) # 必须拷贝，后面要用到 y\n",
    "    y_train[unlabeled_indices]=-1 # 未标记样本的标记设定为 -1\n",
    "\n",
    "    fig=plt.figure()\n",
    "    ax=fig.add_subplot(1,1,1)\n",
    "    alphas=np.linspace(0.01,0.99,num=10,endpoint=True)\n",
    "    Ks=[1,2,3,4,5,8,10,15,20,25,30,35,40,50]\n",
    "    colors=((1,0,0),(0,1,0),(0,0,1),(0.5,0.5,0),(0,0.5,0.5),(0.5,0,0.5),\n",
    "        (0.4,0.6,0),(0.6,0.4,0),(0,0.6,0.4),(0.5,0.3,0.2),) # 颜色集合，不同曲线用不同颜色\n",
    "    ## 训练并绘图\n",
    "    for alpha,color in zip(alphas,colors):\n",
    "        scores=[]\n",
    "        for K in Ks:\n",
    "            clf=LabelPropagation(max_iter=100,n_neighbors=K,alpha=alpha,kernel='knn')\n",
    "            clf.fit(X,y_train)\n",
    "            scores.append(clf.score(X[unlabeled_indices],y[unlabeled_indices]))\n",
    "        ax.plot(Ks,scores,label=r\"$\\alpha=%s$\"%alpha,color=color)\n",
    "\n",
    "    ### 设置图形\n",
    "    ax.set_xlabel(r\"$k$\")\n",
    "    ax.set_ylabel(\"score\")\n",
    "    ax.legend(loc=\"best\")\n",
    "    ax.set_title(\"LabelPropagation knn kernel\")\n",
    "    plt.show()\n",
    "    \n",
    "data=load_data() # 获取半监督分类数据集\n",
    "test_LabelPropagation_knn(*data)# 调用 test_LabelPropagation_knn"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
